package vn.com.epi.log;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

import vn.com.epi.web.Application;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;

public class LogImporter {

	private ArrayListMultimap<String, UserRecord> uMap;
	private Map<Integer, ArticleRecord> aMap;

	public LogImporter() {
		uMap = ArrayListMultimap.create();
		aMap = Maps.newHashMap();
	}

	public void loadData(List<String> lines) {
		try {
			for (String logLine : lines) {
				String[] chunks = logLine.split(",");
				String user = chunks[1];
				int article = Integer.parseInt(chunks[3]);
				if (!((user.length() == 44) && (user.startsWith("WP8-")))) {
					UserRecord userRow = new UserRecord(logLine);
					uMap.put(user, userRow);
				}
				ArticleRecord articleRow = new ArticleRecord(logLine);
				if (!aMap.containsKey(article))
					aMap.put(article, articleRow);
				else {
					long timestamp = aMap.get(article).getTimestamp();
					int categoryId = aMap.get(article).getCategoryId();
					if (articleRow.getCategoryId() == 0 && categoryId > 0)
						articleRow.setCategoryId(categoryId);
					articleRow.setTimestamp(Math.min(articleRow.getTimestamp(),	timestamp));
					aMap.put(article, articleRow);
				}
			}
		} catch (Exception e) {

		}
	}

	private void importUser() {
		Connection connection = null;
		Statement stmt = null;
		ResultSet rs = null;
		int num = 0;
		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
			connection = DriverManager.getConnection(Application.connectionUrl);
			CallableStatement cs = connection.prepareCall("{call UpdateUser(?, ?, ?)}");
			for (String userId : uMap.keySet()) {
				List<UserRecord> list = uMap.get(userId);
				StringBuilder visitedArticleIds = new StringBuilder();
				StringBuilder visitedTimestamps = new StringBuilder();
				int count = 0;
				for (UserRecord record : list) {
					visitedArticleIds.append(record.getArticleId()).append(",");
					visitedTimestamps.append(record.getTimestamp()).append(",");
					count++;
					if (count == 20)
						break;
				}
				if (visitedArticleIds.length() > 0) {
					visitedArticleIds.deleteCharAt(visitedArticleIds.length() - 1);
					visitedTimestamps.deleteCharAt(visitedTimestamps.length() - 1);
					cs.setString(1, userId);
					cs.setString(2, visitedArticleIds.toString());
					cs.setString(3, visitedTimestamps.toString());
					cs.addBatch();
					num++;				}
			}
			if (num > 0)
				cs.executeBatch();
			connection.close();
		}

		catch (Exception e) {
		} finally {
			if (rs != null)
				try {
					rs.close();
				} catch (Exception e) {
				}
			if (stmt != null)
				try {
					stmt.close();
				} catch (Exception e) {
				}
			if (connection != null)
				try {
					connection.close();
				} catch (Exception e) {
				}
		}
	}

	private void importArticle() {
		Connection connection = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
			connection = DriverManager.getConnection(Application.connectionUrl);
			CallableStatement cs = connection
					.prepareCall("{call UpdateArticle(?, ?, ?)}");
			for (int articleId : aMap.keySet()) {
				ArticleRecord record = aMap.get(articleId);
				cs.setInt(1, articleId);
				cs.setInt(2, record.getCategoryId());
				cs.setLong(3, record.getTimestamp());
				cs.addBatch();
			}
			cs.executeBatch();
			connection.close();
		}

		catch (Exception e) {
		} finally {
			if (rs != null)
				try {
					rs.close();
				} catch (Exception e) {
				}
			if (stmt != null)
				try {
					stmt.close();
				} catch (Exception e) {
				}
			if (connection != null)
				try {
					connection.close();
				} catch (Exception e) {
				}
		}
	}

	public void run() {
		try {
			importUser();
			importArticle();
		} catch (Exception e) {
		}
	}
}
